﻿using CommonBehaviors.Actions;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.Helpers;
using Styx.Pathing;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Globalization;
using System.Diagnostics;
using System.Windows.Media;
using Lua = Styx.WoWInternals.Lua;
using Action = Styx.TreeSharp.Action;

namespace RoguePvE
{
    public partial class Main : CombatRoutine
    {
        public override string Name { get { return "Rudge - Subtlety PvE by teamfe"; } }
        public override WoWClass Class { get { return WoWClass.Rogue; } }
        public LocalPlayer Me { get { return StyxWoW.Me; } }

        public override Composite CombatBehavior { get { return CreateCombat(); } }
        public override Composite PreCombatBuffBehavior { get { return PreCombatBuffs(); }}

        public override bool WantButton { get { return true; } }
        public override void OnButtonPress()
        {

        }

        public override void Initialize()
        {
            log("Rudge - Subtlety PvE by teamfe loaded...", Colors.LightGreen);
        }
        public override void Pulse()
        {

        }
        public void log(string Msg, Color color)
        {
            Logging.Write(color, Msg);
        }
        enum Spells
        {
            backStab = 53,
            ambush = 8676,
            crimsonTempest = 121411,
            eviscerate = 2098,
            fanOfKnives = 51723,
            hemorrhage = 16511,
            kick = 1766,
            premeditation = 14183,
            preparation = 14185,
            recuperate = 73651,
            redirect = 73981,
            rupture = 1943,
            shadowBlades = 121471,
            shadowDance = 51713,
            shiv = 5938,
            sliceAndDice = 5171,
            tricksOfTheTrade = 57934,
            vanish = 1856,
            berserking = 26297,
            bloodFury = 20572

        }
        enum Items
        {
            virmensBite = 76089
        }
        enum Auras
        {
            stealth = 115191,
            subterfuge = 115192,
            vanish = 115193,
            anticipation = 115189,
            sliceAndDice = 5171,
            masterOfSubtlety = 31665,
            shadowDance = 51713
        }
        enum Debuffs
        {
            findWeakness = 91021,
            rupture = 1943,
            hemo = 89775
        }

        

     
       
        Composite DanceCDS()
        {
            return new Action(ret =>
            {
                if(Me.Race == WoWRace.Troll && SpellManager.CanCast((int)Spells.berserking))
                {
                    if(SpellManager.Cast((int)Spells.berserking))
                    log("Berserking", Colors.LightGreen);
                }
                if(Me.Race == WoWRace.Orc && SpellManager.CanCast((int)Spells.bloodFury))
                {
                    if(SpellManager.Cast((int)Spells.bloodFury))
                    log("Blood Fury", Colors.LightGreen);
                }
            });
        }
        Composite ArcaneTorrent()
        {
            return new Action(ret =>
            {
                if(SpellManager.Cast(25046))
                log("Arcane Torrent", Colors.LightGreen);
            });
        }
        Composite ShadowBlades()
        {
            return new Action(ret =>
            {
                if(SpellManager.Cast((int)Spells.shadowBlades))
                log("Shadow Blades", Colors.LightGreen);
            });
        }
        Composite Premeditation()
        {
            return new Action(ret =>
            {
                if(SpellManager.Cast((int)Spells.premeditation))
                log("Premiditation", Colors.Red);
            });
        }
        Composite Ambush()
        {
            return new Action(ret =>
            {
                if(SpellManager.Cast((int)Spells.ambush))
                log("Ambush", Colors.Red);
            });
        }
        Composite ShadowDance()
        {
            return new Action(ret =>
            {
                if(SpellManager.Cast((int)Spells.shadowDance))
                log("Shadow Dance", Colors.LightGreen);
            });
        }
        Composite PoolForDance()
        {
            return new Action(ret =>
            {
                log("Shadow Dance Soon - Pooling", Colors.LightGreen);
            });
        }
        Composite Vanish()
        {
            return new Action(ret =>
            {
                if (SpellManager.Cast((int)Spells.vanish))
                {
                    log("Vanish", Colors.LightGreen);
                    if (SpellManager.Cast((int)Spells.ambush))
                    {
                        log("Ambush", Colors.LightGreen);
                    }
                }
            });
        }
        Composite PoolForVanish()
        {
            return new Action(ret =>
            {
                log("Vanish Soon - Pooling", Colors.LightGreen);
            });
        }
        Composite Preparation()
        {
            return new Action(ret =>
            {
                if (SpellManager.Cast((int)Spells.preparation))
                {
                    log("Preparation", Colors.LightGreen);
                }
            });
        }
        public bool ShouldPool()
        {
            if (buffTimeLeft((int)Auras.sliceAndDice, Me) < 3 || debuffTimeLeft((int)Debuffs.rupture, Me.CurrentTarget) < 2)
            {
                return false;
            }
            else if (Me.CurrentEnergy <= 65)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        Composite Generate()
        {
            return new Action(ret =>
            {

                if (!buffExists((int)Auras.masterOfSubtlety, Me) && !buffExists((int)Auras.shadowDance, Me) && !debuffExists((int)Debuffs.findWeakness, Me.CurrentTarget) && ShouldPool())
                {
                    
                }
                else if (!Me.IsBehind(Me.CurrentTarget) || debuffTimeLeft((int)Debuffs.hemo, Me.CurrentTarget) < 3)
                {
                    if (Me.IsBehind(Me.CurrentTarget) && SpellManager.CanCast((int)Spells.ambush))
                    {
                        if (SpellManager.Cast((int)Spells.ambush))
                        {
                            log("Ambush", Colors.Red);
                        }
                    }
                    else if(SpellManager.Cast((int)Spells.hemorrhage))
                    log("Hemorrhage", Colors.Red);
                }
                else if (Me.IsBehind(Me.CurrentTarget) && SpellManager.CanCast((int)Spells.backStab))
                {
                    if(SpellManager.CanCast((int)Spells.ambush))
                    {
                        if(SpellManager.Cast((int)Spells.ambush))
                        {
                            log("Ambush", Colors.Red);
                        }
                    }
                    else if(SpellManager.Cast((int)Spells.backStab))
                    log("Backstab", Colors.Red);
                }
            });
        }
        Composite Finisher()
        {
            return new Action(ret =>
            {
                if (buffTimeLeft((int)Auras.sliceAndDice, Me) < 4000)
                {
                    if(SpellManager.Cast((int)Spells.sliceAndDice))
                    log("Slice and Dice", Colors.LightGreen);
                }
                else if (debuffTimeLeft((int)Debuffs.rupture, Me.CurrentTarget) < 4000)
                {
                    if(SpellManager.Cast((int)Spells.rupture))
                    log("Rupture", Colors.Red);
                }
                else if (buffTimeLeft((int)Auras.sliceAndDice, Me) > 6000 && debuffTimeLeft((int)Debuffs.rupture, Me.CurrentTarget) < 6000 || Me.CurrentEnergy >= 80)
                {
                    if(SpellManager.Cast((int)Spells.eviscerate))
                    log("Eviscerate", Colors.Red);
                }
            });
        }
        public bool debuffExists(int Debuff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                WoWAura aura = onTarget.GetAllAuras().FirstOrDefault(a => a.SpellId == Debuff && a.CreatorGuid == Me.Guid);
                if (aura != null)
                {
                    return true;
                }
            }
            return false;
        }
        public bool buffExists(int Buff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                var Results = onTarget.GetAuraById(Buff);
                if (Results != null)
                    return true;
            }
            return false;
        }
        public double buffTimeLeft(int Buff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                var Results = onTarget.GetAuraById(Buff);
                if (Results != null)
                {
                    if (Results.TimeLeft.TotalMilliseconds > 0)
                        return Results.TimeLeft.TotalMilliseconds;
                }
            }
            return 0;
        }
        public double debuffTimeLeft(int Debuff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                WoWAura aura = onTarget.GetAllAuras().FirstOrDefault(a =>
                    a.SpellId == Debuff
                    && a.CreatorGuid == Me.Guid);

                if (aura == null)
                {
                    return 0;
                }
                return aura.TimeLeft.TotalMilliseconds;
            }
            return 0;
        }
        public static TimeSpan GetCoolDown(int spell)
        {
            SpellFindResults results;
            SpellManager.FindSpell(spell, out results);
            return results.Override.CooldownTimeLeft;
        }
        public bool ShouldUseCDs()
        {
            if ((Me.CurrentTarget.IsBoss || Me.CurrentTarget.Name == "Training Dummy" || Me.CurrentTarget.Name == "Raider's Training Dummy") && Me.IsBehind(Me.CurrentTarget) && Me.CurrentTarget.Distance <= 10 && Me.IsAutoAttacking)
            {
                return true;
            }
            return false;
        }
        Composite CreateCombat()
        {
            
                return new PrioritySelector(
                    new Decorator(ret => buffExists((int)Auras.shadowDance, Me) && (SpellManager.CanCast(((int)Spells.berserking)) || SpellManager.CanCast(((int)Spells.bloodFury))),
                        DanceCDS()),
                    new Decorator(ret => Me.Race == WoWRace.BloodElf && Me.CurrentEnergy < 60 && SpellManager.CanCast(25046),
                        ArcaneTorrent()),
                    new Decorator(ret => ShouldUseCDs() && SpellManager.CanCast((int)Spells.shadowBlades),
                        ShadowBlades()),
                    new Decorator(ret => SpellManager.CanCast((int)Spells.premeditation),
                        Premeditation()),
                    new Decorator(ret => Me.ComboPoints <= 4 && SpellManager.CanCast((int)Spells.ambush),
                        Ambush()),
                    new Decorator(ret => ShouldUseCDs() && Me.CurrentEnergy >= 75 && SpellManager.CanCast((int)Spells.shadowDance) && !buffExists((int)Auras.subterfuge, Me) && !buffExists((int)Auras.stealth, Me) && !buffExists((int)Auras.vanish, Me),
                        ShadowDance()),
                    new Decorator(ret => ShouldUseCDs() && Me.CurrentEnergy <= 75 && !buffExists((int)Auras.subterfuge, Me) && SpellManager.CanCast((int)Spells.shadowDance),
                        PoolForDance()),
                    new Decorator(ret => ShouldUseCDs() && Me.CurrentEnergy >= 45 && SpellManager.CanCast((int)Spells.vanish) && !buffExists((int)Auras.subterfuge, Me) && !SpellManager.CanCast((int)Spells.shadowDance) && !buffExists((int)Auras.shadowDance, Me) && !buffExists((int)Auras.masterOfSubtlety, Me) && !debuffExists((int)Debuffs.findWeakness, Me.CurrentTarget),
                        Vanish()),
                    new Decorator(ret => ShouldUseCDs() && Me.CurrentEnergy <= 45 && SpellManager.CanCast((int)Spells.vanish) && !buffExists((int)Auras.subterfuge, Me) && !buffExists((int)Auras.shadowDance, Me),
                        PoolForVanish()),
                    new Decorator(ret => Me.ComboPoints <= 4,
                        Generate()),
                    new Decorator(ret => Me.ComboPoints == 5,
                        Finisher())
                    );
            
            
        }
        Composite DeadlyPoison()
        {
            return new Action(ret =>
           {
               if(SpellManager.Cast(2823))
               log("Deadly Poison", Colors.LightGreen);
           });

        }
        Composite LeechingPoison()
        {
            return new Action(ret =>
            {
                if(SpellManager.Cast(108211))
                log("Leeching Poison", Colors.LightGreen);
            });
        }
        Composite PreCombatBuffs()
        {
             return new PrioritySelector(
                 new Decorator(ret => buffExists((int)Auras.vanish, Me) && SpellManager.CanCast((int)Spells.ambush),
                     Ambush()),
                 new Decorator(ret => !buffExists(2823, Me),
                     DeadlyPoison()),
                 new Decorator(ret => !buffExists(108211, Me),
                     LeechingPoison())
                 );
        }


    }
}




